In [2]:
import pandas as pd
import numpy as np
"group by"操作通常涉及下面几个步骤:
其中applying通常是下面三个类型的函数:
groupby和SQL中的GROUP BY很像:
In [ ]:
SELECT Column1, Column2, mean(Column3), sum(Column4)
FROM SomeTable
GROUP BY Column1, Column2
In [ ]:
# 默认按照axis=0分组
grouped = obj.groupby(key)
grouped = obj.groupby(key, axis=1)
grouped = obj.groupby([key1, key2])
In [4]:
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': np.random.randn(8),
'D': np.random.randn(8)})
In [5]:
df
Out[5]:
In [7]:
grouped = df.groupby('A')
grouped = df.groupby(['A', 'B'])
把DataFrame按照列分组,比如第一列为一组,第二、三列为另一组。相比于按行分组,按列分组用处不大。
In [22]:
def get_letter_type(letter):
if letter.lower() in 'aeiou':
return 'vowel'
else:
return 'consonant'
grouped = df.groupby(get_letter_type, axis=1)
In [9]:
grouped
Out[9]:
groupby的结果默认会对group key排序,可以通过参数sort=False来组织排序,提高性能:
In [10]:
df2 = pd.DataFrame({'X': ['B', 'B', 'A', 'A'], 'Y': [1, 2, 3, 4]})
In [11]:
df2.groupby('X').sum()
Out[11]:
In [13]:
df2.groupby('X', sort=False).sum()
Out[13]:
分组后,各个组内数据的顺序和原来DataFrame内数据顺序一致。
In [14]:
df3 = pd.DataFrame({'X': ['A', 'B', 'A', 'B'], 'Y': [1, 4, 3, 2]})
In [15]:
df3.groupby('X').get_group('A')
Out[15]:
In [17]:
df3.groupby('X').get_group('B')
Out[17]:
groups属性是一个字典,每个key就是group key
In [20]:
df.groupby('A').groups
Out[20]:
In [21]:
df.groupby(get_letter_type, axis=1).groups
Out[21]:
可以对grouped调用len()函数,会得到gruops这个字典的大小
In [23]:
grouped = df.groupby(['A', 'B'])
In [24]:
grouped.groups
Out[24]:
In [25]:
len(grouped)
Out[25]:
想查看groupby的属性,按TAB
In [ ]:
gb.<TAB>
In [26]:
grouped = df.groupby('A')
In [28]:
for name, group in grouped:
print(name)
print(group)
如果根据多个key进行groupby,则name类型是tuple:
In [29]:
for name, group in df.groupby(['A', 'B']):
print(name)
print(group)
使用get_group()函数:
In [31]:
grouped.get_group('bar')
Out[31]:
In [32]:
df.groupby(['A', 'B']).get_group(('bar', 'one'))
Out[32]:
一旦数据分组完成,就可以对各个组的数据应用某个函数了,典型的例子是调用aggregate/agg:
In [33]:
grouped = df.groupby('A')
In [34]:
grouped.aggregate(np.sum)
Out[34]:
In [37]:
for name, group in grouped:
print(name)
print(group)
可以看到,集成后的数据包含组名,并且组名作为行索引。如果groupby分组时有多个group key,集成后数据默认含有层级索引,可以通过as_index=False参数来去掉索引:
In [46]:
grouped = df.groupby(['A', 'B'], as_index=False)
In [47]:
grouped.aggregate(np.sum)
Out[47]:
In [48]:
df.groupby('A', as_index=False).sum()
Out[48]:
除了使用as_index参数,也可以使用reset_index()去掉组名构成的多级索引:
In [50]:
df.groupby(['A', 'B']).sum().reset_index()
Out[50]:
In [52]:
grouped.size() # 返回各个组的size
Out[52]:
In [54]:
grouped = df.groupby('A')
In [55]:
grouped['C'].agg([np.sum, np.mean, np.std])
Out[55]:
In [56]:
grouped.agg([np.sum, np.mean, np.std])
Out[56]:
In [57]:
grouped.agg({'C': np.sum,
'D': lambda x: np.std(x, ddof=1)})
Out[57]:
一些常用的数据集成函数,比如sum、mean、std、sem,都有优化过的Cython实现:
In [58]:
df.groupby('A').sum()
Out[58]:
In [59]:
df.groupby(['A', 'B']).mean()
Out[59]:
In [ ]:
In [ ]:
In [ ]: